package com.mini.mybatis.builder.xml;

import com.mini.mybatis.datasource.DataSourceFactory;
import com.mini.mybatis.datasource.druid.DruidDataSourceFactory;
import com.mini.mybatis.io.Resources;
import com.mini.mybatis.session.Configuration;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

/**
 * XML配置构建器 - 解析mybatis-config.xml配置文件
 */
public class XMLConfigBuilder {
    
    private static final Logger logger = LoggerFactory.getLogger(XMLConfigBuilder.class);
    
    private Configuration configuration;
    
    public XMLConfigBuilder() {
        this.configuration = new Configuration();
    }
    
    /**
     * 解析配置文件
     * @param inputStream 配置文件输入流
     * @return Configuration对象
     */
    public Configuration parse(InputStream inputStream) {
        try {
            // 使用DOM4J解析XML
            Document document = new SAXReader().read(inputStream);
            Element root = document.getRootElement();
            
            // 解析配置文件
            parseConfiguration(root);
            
            return configuration;
        } catch (DocumentException e) {
            logger.error("解析配置文件失败", e);
            throw new RuntimeException("解析配置文件失败", e);
        }
    }
    
    /**
     * 解析配置根节点
     */
    private void parseConfiguration(Element root) {
        // 解析数据源配置
        parseDataSources(root.element("environments"));
        
        // 解析映射器配置
        parseMappers(root.element("mappers"));
    }
    
    /**
     * 解析数据源配置
     */
    private void parseDataSources(Element environments) {
        if (environments == null) {
            return;
        }
        
        String defaultEnvironment = environments.attributeValue("default");
        List<Element> environmentList = environments.elements("environment");
        
        for (Element environment : environmentList) {
            String id = environment.attributeValue("id");
            
            // 只解析默认环境的数据源
            if (defaultEnvironment.equals(id)) {
                // 解析数据源
                Element dataSourceElement = environment.element("dataSource");
                DataSource dataSource = parseDataSource(dataSourceElement);
                configuration.setDataSource(dataSource);
                break;
            }
        }
    }
    
    /**
     * 解析数据源
     */
    private DataSource parseDataSource(Element dataSourceElement) {
        String type = dataSourceElement.attributeValue("type");
        List<Element> propertyList = dataSourceElement.elements("property");
        
        Properties props = new Properties();
        for (Element property : propertyList) {
            props.setProperty(property.attributeValue("name"), property.attributeValue("value"));
        }
        
        // 创建数据源工厂
        DataSourceFactory dataSourceFactory = getDataSourceFactory(type);
        dataSourceFactory.setProperties(props);
        
        return dataSourceFactory.getDataSource();
    }
    
    /**
     * 获取数据源工厂
     */
    private DataSourceFactory getDataSourceFactory(String type) {
        // 简化实现，这里只支持Druid数据源
        if ("DRUID".equals(type)) {
            return new DruidDataSourceFactory();
        }
        throw new RuntimeException("不支持的数据源类型: " + type);
    }
    
    /**
     * 解析映射器配置
     */
    private void parseMappers(Element mappers) {
        if (mappers == null) {
            return;
        }
        
        List<Element> mapperList = mappers.elements("mapper");
        for (Element mapper : mapperList) {
            String resource = mapper.attributeValue("resource");
            String mapperClass = mapper.attributeValue("class");
            
            if (resource != null && !resource.isEmpty()) {
                // 解析XML映射文件
                InputStream inputStream = Resources.getResourceAsStream(resource);
                XMLMapperBuilder mapperBuilder = new XMLMapperBuilder(inputStream, configuration, resource);
                mapperBuilder.parse();
            } else if (mapperClass != null && !mapperClass.isEmpty()) {
                // 注册映射器接口
                try {
                    Class<?> mapperInterface = Class.forName(mapperClass);
                    configuration.addMapper(mapperInterface);
                } catch (ClassNotFoundException e) {
                    logger.error("找不到映射器类: " + mapperClass, e);
                    throw new RuntimeException("找不到映射器类: " + mapperClass, e);
                }
            }
        }
    }
}